// 1.使用类继承代替"可辨识联合类型"

enum Transportations {
    motorcycle,
    car,
    truck
}

abstract class T {
    abstract type: Transportations;

    abstract run(): void
}

class T1 extends T {
    run(): void {
        throw new Error("Method not implemented.");
    }
    type = Transportations.motorcycle as const;
    constructor(
        public make: number
    ) {
        super()
    }
}

class T2 extends T {
    run(): void {
        throw new Error("Method not implemented.");
    }
    type = Transportations.car as const;
    
    constructor(
        public pow: number
    ) {
        super()
    }
}

class T3 extends T {
    run(): void {
        throw new Error("Method not implemented.");
    }
    type = Transportations.truck as const;
    
    constructor(
        public capacity: number
    ) {
        super()
    }
}

// 小技巧，使用Omit将class转对象类型
type X1 = Omit<T1, never>
type X2 = Omit<T2, never>
type X3 = Omit<T3, never>

type Transporter = T;

class MyController {
    run(x: Transporter) {
        x.run()
    }
}

// 使用OOP的方式，程序的执行结构是确定的，操作数据类型的基类是确定的，因此系统是稳定的
// 所有的run都必须由每一类实现

// CASE1: 使用平台（单例）来为所有的transporter提供服务
class Platform {
    static transporters = new Array<Transporter>
    static controller = new MyController
    static runAll() {
        this.transporters.forEach((transporter) => {
            this.controller.run(transporter)
        });
    }
}

// CASE2: 平台将每一个transporter配备一个独立的控制器
class Platform2 extends Array<[MyController, Transporter]> {
    runAll() {
        this.forEach(([controller, transporter]) => {
            controller.run(transporter)
        });
    }
}

let p = new Platform2;
let ctrl!: MyController;
let trans!: Transporter;
p.push([ctrl, trans])
p.runAll()